package com.example.springboot.controller.参数解析;

import com.example.springboot.bean.Pet;
import com.example.springboot.bean.User;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
public class 参数注解的使用 {
    /**
     * SpringMVC目标方法能写多少种参数类型。取决于"参数解析器"有多少个
     * @PathVariable("id")  可以拿到；路径变量的值
     * @RequestHeader //获取所有请求头   ("User-Agent")  //指定   请求头
     * @CookieValue("_ga") Cookie cookie//获取_ga的Cookie//没有Cookie会报错
     * @RequestBody //获取请求体数据!
     * @RequestParam //或其指定的请求参数  ?后面的
     * 都可以设置参数
     * (value = "指定值",required = false,defaultValue = "屎山")
     * value: 对应的时指定key
     * required:默认true  必须有此key 否则报错
     *          false     可无此key
     * defaultValue  默认值。当无此参数或值为空的时候  给个默认
     *               有默认值 required  就没必要了  因为必定有此key
     *
     * 四大参数处理原理中：
     *  先找XxxHandlerMapping 的第一个
     *  RequestMappingHandlerMapping  存了所有自定义的访问路径
     *  再找到合适的配置器(有以下4个)
     *     {RequestMappingHandlerAdapter@5828}
     *        自己有 @RequestMapping 注解的方法(路径访问)
     *    {HandlerFunctionAdapter@5829}  函数式方法
     *    {HttpRequestHandlerAdapter@5830}
     *    {SimpleControllerHandlerAdapter@5831}
     *
     * 找到后 开始执行合适的配置器
     *  RequestMappingHandlerAdapter//一般都是这个
     *
     *     //执行前  会初始化  参数解析器  确定将要执行的目标方法的每-个参数的值是什么
     *     HandlerMethodArgumentResolver//参数解析器  学习的时候26种  就是参数注解
     *        XxxMethodArgumentResolver//Xxx就像@PathVariable这样的
     *        确定将要执行的目标方法的每一个参数的值是什么;
     *        增强for循环遍历确定 (当用到此参数解析器的话，会放到缓存里)
     *        SpringMVC 目标方法能写多少种参数类型。取决于参数解析器
     *        在 request 的UnlPathHelper(保存所有路径信息)中 找到对应的信息
     *        遍历所有的 参数 并解析
     *
     *     在进行invokeForRequest()方法 利用反射  执行目标方法
     *     也就是被 RequestMapping 注解的方法
     *
     *     返回值处理器  约15种 XxxMethodReturnValueHandler .
     *     支持哪几种返回值(如 map，Model,ModelAndView，ModelMap等)
     *
     *
     */

    @GetMapping("/car/{id}/owner/{username}")
    public Map<String,Object> getCar(@PathVariable("id") Integer id,//达到指定的路径变量的值
                                     @PathVariable("username") String username,
                                     @PathVariable Map<String,String> pv,//获取所有路径的变量信息
                                     @RequestHeader("User-Agent") String userAgent,//获得指定请求头
                                     @RequestHeader Map<String,String> header,//获取所有请求头
                                     @RequestParam("age") Integer age,//？后面的指定
                                     @RequestParam("inters") List<String> inters,//？后面的
//                                     @CookieValue("_ga") String ga,//找相关Cook的值
//                                     @CookieValue("_ga") Cookie cookie,//找到相关的整个Cookie对象
                                     @RequestParam Map<String,String> params//？后面的全部
//路径  car/3/owner/list?age=18&inters=basketball&inters=game&nnn=qqq
    ){

        Map<String,Object> map=new HashMap<>();
        map.put("id",id);
        map.put("username",username);
        map.put("pv",pv);
        map.put("userAgent",userAgent);//获得指定请求头
        map.put("header",header);//获取所有请求头
        map.put("age",age);
        map.put("inters",inters);
        map.put("params",params);
//        map.put("_ga",ga);
//        System.out.println(cookie);
        return map;

    }

    @PostMapping("/requestBody")//获取请求体数据  也就是？后的
    public Map postMethod(@RequestBody String content){
        Map<String,Object> map=new HashMap<>();
        map.put("content",content);
        return map;
    }

    @PostMapping("/UserDemo")//获取请求体数据
    public User UserDemo(@RequestBody User user){
        /**
         * 自定义类型参数 封装POJO
         * ServletModelAttributeMethodProcessor  这个参数处理器支持
         *  是否为简单类型(Enum CharSequence  Number  Date Temporal URI URL Locale Class).
         *
         *  User 不是简单类型  他会创建一个空的 User
         *  因为html传到后端的式text文本类型，他会经过 converters 类型转换器(很多)
         *  遍历循环 找到指定转换器   转换成指定的 User 的属性的类型   并反射赋值
         *  //可以自己创建转换器并添加
         *  @FunctionalInterfacepublic interface Converter<S, T>
         *      converter那个可以将这个数据类型（request带来参数的字符串）
         *      转换到指定的类型（JavaBean -- Integer）
         *
         */
        return user;
    }

    @PostMapping("/Pet")//获取请求体数据
    public Pet UserDemo(Pet pet){
        /**
         * 自定义类型参数 封装POJO
         * ServletModelAttributeMethodProcessor  这个参数处理器支持
         *  是否为简单类型(Enum CharSequence  Number  Date Temporal URI URL Locale Class).
         *
         *  User 不是简单类型  他会创建一个空的 User
         *  因为html传到后端的式text文本类型，他会经过 converters 类型转换器(很多)
         *  遍历循环 找到指定转换器   转换成指定的 User 的属性的类型   并反射赋值
         *  //可以自己创建转换器并添加
         *  @FunctionalInterfacepublic interface Converter<S, T>
         *      converter那个可以将这个数据类型（request带来参数的字符串）
         *      转换到指定的类型（JavaBean -- Integer）
         *
         */
        return pet;
    }

}
